/*
 * Created on 2005-3-12
 *
 */
package bma.common.langutil.bean.impl;

import java.lang.reflect.Member;
import java.lang.reflect.Method;

import bma.common.langutil.bean.AccessType;
import bma.common.langutil.core.DirectInvoker;
import bma.common.langutil.core.ExceptionUtil;

/**
 * 
 * @author guanzhong
 * @since 1.0 (imported from BMA.ESP Project)
 * 
 */
public class BeanObjectPropertyNative extends BeanObjectPropertyAbstract {

	private Method getMethod;

	private Method setMethod;

	public BeanObjectPropertyNative() {
		super();
	}

	@Override
	public Member getPrototype() {
		Member m = super.getPrototype();
		if (m != null) {
			return super.getPrototype();
		}
		if (getMethod != null)
			return getMethod;
		return setMethod;
	}

	@Override
	public boolean accessible(AccessType type) {

		if (!super.accessible(type))
			return false;

		switch (type) {
		case GET:
			return getMethod != null;
		case SET:
			return setMethod != null;
		default:
			return false;
		}
	}

	@Override
	public Object get(Object thisObject) {
		if (thisObject == null) {
			throw new NullPointerException("this object");
		}
		if (getMethod == null) {
			throw new NullPointerException("getMethod[" + getName() + "]");
		}

		try {
			return DirectInvoker.invoke(thisObject, getMethod, null);
		} catch (Exception e) {
			throw ExceptionUtil.throwRuntime(e);
		}
	}

	@Override
	public void set(Object thisObject, Object value) {
		if (thisObject == null) {
			throw new NullPointerException("this object");
		}
		if (setMethod == null) {
			throw new NullPointerException("setMethod[" + getName() + "]");
		}

		try {
			DirectInvoker.invoke(thisObject, setMethod, new Object[] { value });
		} catch (Exception e) {
			throw ExceptionUtil.throwRuntime(e);
		}
	}

	/**
	 * @return Returns the getMethod.
	 */
	public Method getGetMethod() {
		return getMethod;
	}

	/**
	 * @param getMethod
	 *            The getMethod to set.
	 */
	public void setGetMethod(Method getMethod) {
		this.getMethod = getMethod;
	}

	/**
	 * @return Returns the setMethod.
	 */
	public Method getSetMethod() {
		return setMethod;
	}

	/**
	 * @param setMethod
	 *            The setMethod to set.
	 */
	public void setSetMethod(Method setMethod) {
		this.setMethod = setMethod;
	}

	@Override
	public String toString() {
		return "NS:" + super.toString();
	}
}
